import type { ConversationFlow } from '../index'
import type { CommentInfo } from '../types'
import { logger } from '../../../../../types/constants'
import { SYMBOLS } from '../../../../../types/interfaces'

export class ConversationFlowReport {
  readonly name: string = 'ConversationFlowReport'
  private static instance: ConversationFlowReport
  // 全局匹配统计
  matchStatistics: {
    exact: Set<string>
    fuzzy: Set<string>
    prefixSuffix: Set<string>
    failed: number
  } = {
    exact: new Set<string>(), // 精确匹配的评论ID集合
    fuzzy: new Set<string>(), // 模糊匹配的评论ID集合
    prefixSuffix: new Set<string>(), // 前后缀匹配的评论ID集合
    failed: 0, // 匹配失败次数
  }

  constructor(private flowInstance: ConversationFlow) {
  }

  /**
   * 获取单例实例
   */
  public static getInstance(flowInstance: ConversationFlow): ConversationFlowReport {
    if (!ConversationFlowReport.instance) {
      ConversationFlowReport.instance = new ConversationFlowReport(flowInstance)
    }
    return ConversationFlowReport.instance
  }

  /**
   * 打印统计信息
   */
  printStatistics(): void {
    const stats = this.getStatistics()

    logger.important(`[${this.name}] 评论引用关系统计`, stats)

    this.printMatchStatistics()

    if (stats.commentsWithUnmatchedQuotes > 0) {
      logger.warn(`[${this.name}] [可忽略] ${stats.commentsWithUnmatchedQuotes} 条评论存在未匹配的引用块`, '由于用户引用格式不统一，可能会出现此类情况，不影响功能运行')
      logger.info(`[${this.name}] 详细分类:`, stats.unmatchedQuoteDetails)

      // 输出具体的未匹配评论信息
      this.flowInstance.commentsMap.forEach((commentInfo) => {
        if (commentInfo.hasUnmatchedQuotes) {
          this.printCommentUnmatchedDetails(commentInfo)
        }
      })
    }
  }

  /**
   * 打印详细的匹配统计信息
   */
  private printMatchStatistics(): void {
    const stats = this.getMatchStatistics()

    logger.info(`[${this.name}] 匹配类型统计详情`, {
      totalRelationships: stats.totalRelationships,
      matchTypes: {
        exact: { count: stats.exact.count, comments: stats.exact.comments },
        fuzzy: { count: stats.fuzzy.count, comments: stats.fuzzy.comments },
        prefixSuffix: { count: stats.prefixSuffix.count, comments: stats.prefixSuffix.comments },
      },
      failedMatches: stats.failed,
      successRate: stats.successRate,
    })

    // 详细输出每种匹配类型的评论信息
    this.printDetailedMatchStatistics(stats)
  }

  /**
   * 获取匹配统计信息
   */
  private getMatchStatistics(): {
    totalRelationships: number
    exact: { count: number, comments: string[] }
    fuzzy: { count: number, comments: string[] }
    prefixSuffix: { count: number, comments: string[] }
    failed: number
    successRate: string
  } {
    const exactComments = Array.from(this.matchStatistics.exact)
    const fuzzyComments = Array.from(this.matchStatistics.fuzzy)
    const prefixSuffixComments = Array.from(this.matchStatistics.prefixSuffix)

    const totalRelationships = exactComments.length + fuzzyComments.length + prefixSuffixComments.length
    const totalAttempts = totalRelationships + this.matchStatistics.failed
    const successRate = totalAttempts > 0 ? `${((totalRelationships / totalAttempts) * 100).toFixed(1)}%` : '0%'

    return {
      totalRelationships,
      exact: { count: exactComments.length, comments: exactComments },
      fuzzy: { count: fuzzyComments.length, comments: fuzzyComments },
      prefixSuffix: { count: prefixSuffixComments.length, comments: prefixSuffixComments },
      failed: this.matchStatistics.failed,
      successRate,
    }
  }

  /**
   * 打印详细的匹配统计信息
   */
  private printDetailedMatchStatistics(stats: any): void {
    logger.important(`[${this.name}] 匹配类型详细统计`)

    // 精确匹配
    if (stats.exact.count > 0) {
      logger.info(`[${this.name}] ${SYMBOLS.STATUS.SUCCESS} 精确匹配: ${stats.exact.count} 个`, {
        comments: stats.exact.comments.map((id: string) => {
          const comment = this.flowInstance.commentsMap.get(id)
          return comment ? `#${comment.floorNumber}` : id
        }),
      })
    }

    // 模糊匹配
    if (stats.fuzzy.count > 0) {
      logger.info(`[${this.name}] ${SYMBOLS.STATUS.SUCCESS} 模糊匹配: ${stats.fuzzy.count} 个`, {
        comments: stats.fuzzy.comments.map((id: string) => {
          const comment = this.flowInstance.commentsMap.get(id)
          return comment ? `#${comment.floorNumber}` : id
        }),
      })
    }

    // 前后缀匹配
    if (stats.prefixSuffix.count > 0) {
      logger.info(`[${this.name}] ${SYMBOLS.STATUS.INFO} 前后缀匹配: ${stats.prefixSuffix.count} 个`, {
        comments: stats.prefixSuffix.comments.map((id: string) => {
          const comment = this.flowInstance.commentsMap.get(id)
          return comment ? `#${comment.floorNumber}` : id
        }),
      })
    }

    logger.info(`[${this.name}] 总体成功率: ${stats.successRate} （失败 ${stats.failed} 个）`)
  }

  /**
   * 获取评论的引用关系统计
   */
  getStatistics(): {
    totalComments: number
    totalRelationships: number
    commentsWithQuotes: number
    commentsWithUnmatchedQuotes: number
    unmatchedQuoteDetails: {
      failedMatches: number
      skippedShortQuotes: number
      selfReferences: number
    }
  } {
    const totalComments = this.flowInstance.commentsMap.size
    let totalRelationships = 0
    let commentsWithQuotes = 0
    let commentsWithUnmatchedQuotes = 0
    let failedMatches = 0
    let skippedShortQuotes = 0
    let selfReferences = 0

    this.flowInstance.commentsMap.forEach((comment) => {
      if (comment.quoteTargets.length > 0) {
        commentsWithQuotes++
        totalRelationships += comment.quoteTargets.length
      }

      if (comment.hasUnmatchedQuotes) {
        commentsWithUnmatchedQuotes++

        // 分类统计未匹配引用
        comment.unmatchedQuotePreviews.forEach((preview) => {
          if (preview.includes('[过短:')) {
            skippedShortQuotes++
          }
          else if (preview.includes('[自引用]')) {
            selfReferences++
          }
          else if (preview.includes('[匹配失败]')) {
            failedMatches++
          }
        })
      }
    })

    return {
      totalComments,
      totalRelationships,
      commentsWithQuotes,
      commentsWithUnmatchedQuotes,
      unmatchedQuoteDetails: {
        failedMatches,
        skippedShortQuotes,
        selfReferences,
      },
    }
  }

  /**
   * 输出单条评论的未匹配详情
   *
   * @param commentInfo - 评论信息对象
   */
  private printCommentUnmatchedDetails(commentInfo: CommentInfo): void {
    const shortQuotes = commentInfo.unmatchedQuotePreviews.filter(p => p.includes('[过短:'))
    const selfRefQuotes = commentInfo.unmatchedQuotePreviews.filter(p => p.includes('[自引用]'))
    const failedQuotes = commentInfo.unmatchedQuotePreviews.filter(p => p.includes('[匹配失败]'))
    const otherQuotes = commentInfo.unmatchedQuotePreviews.filter(p =>
      !p.includes('[过短:') && !p.includes('[自引用]') && !p.includes('[匹配失败]'),
    )

    logger.debug(`[${this.name}] ${SYMBOLS.OTHERS.COMMENT} 评论 #${commentInfo.floorNumber} 未匹配引用`)

    // 分类输出不同类型的未匹配引用
    if (shortQuotes.length > 0) {
      shortQuotes.forEach((preview) => {
        logger.debug(`[${this.name}] • ${preview}`)
      })
    }

    if (selfRefQuotes.length > 0) {
      selfRefQuotes.forEach((preview) => {
        logger.debug(`[${this.name}] • ${preview}`)
      })
    }

    if (failedQuotes.length > 0) {
      failedQuotes.forEach((preview, index) => {
        logger.debug(`[${this.name}] ${index + 1}. ${preview}`)
      })
    }

    if (otherQuotes.length > 0) {
      otherQuotes.forEach((preview) => {
        logger.debug(`[${this.name}] • ${preview}`)
      })
    }
  }

  /**
   * 重置匹配统计
   */
  resetMatchStatistics(): void {
    this.matchStatistics = {
      exact: new Set<string>(),
      fuzzy: new Set<string>(),
      prefixSuffix: new Set<string>(),
      failed: 0,
    }
  }
}
